package com.taxinfo.controller;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONNull;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.taxinfo.AbstractApp;
import com.taxinfo.App;
import com.taxinfo.common.ClientSession;
import com.taxinfo.component.alert.MyAlert;
import com.taxinfo.pojo.dto.LoginDto;
import com.taxinfo.pojo.dto.SystemSubMatchingBO;
import com.taxinfo.pojo.vo.LoginInfo;
import com.taxinfo.pojo.vo.SoftwareMapModel;
import com.taxinfo.pojo.vo.SubMatching;
import com.taxinfo.service.LoginService;
import com.taxinfo.service.SoftwareMapModelService;
import com.taxinfo.service.SubMatchingService;
import com.taxinfo.utils.DesUtils;
import com.taxinfo.utils.ToolManager;
import com.taxinfo.utils.SaltUtil;
import com.taxinfo.utils.SpringUtil;
import com.taxinfo.view.ForgetPasswordView;
import de.felixroske.jfxsupport.FXMLController;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ResourceBundle;

import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.VBox;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

@FXMLController
public class WelcomeController implements Initializable {

    @FXML
    private VBox vbRoot;
    @FXML
    public TextField tf_username;
    @FXML
    private Button btn_Login;
    @FXML
    public Button btn_forget;
    @FXML
    private PasswordField pf_password;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        vbRoot.setStyle("-fx-background-image: url('images/backdrop.png'); -fx-background-size: cover;");
        tf_username.setText("liu123456@163.com");
        pf_password.setText("a123456");
    }

    @FXML
    private void login() {
        String username = tf_username.getText().trim();
        String password = pf_password.getText().trim();
        // 用户名密码非空校验
        if ("".equals(username.trim())) {
            new MyAlert(AlertType.WARNING, "用户名不能为空").show();
            return;
        }
        if ("".equals(password.trim())) {
            new MyAlert(AlertType.WARNING, "密码不能为空").show();
            return;
        }

        btn_Login.setText("登录验证中...");

        VerifyTask vTask = new VerifyTask(username, password);
        new Thread(vTask).start();
        vTask.valueProperty().addListener((observable, oldValue, newValue) -> {
            boolean isLogin =false;
            String validTime="";
            try {
                isLogin =  ToolManager.validateLicense();
                validTime = ToolManager.getValidTime();
                if(!isLogin){
                    new MyAlert(AlertType.WARNING, "税智报软件已过期,请联系管理员授权！").showAndWait();
                }
            } catch (Exception e) {
                new MyAlert(AlertType.WARNING, "未获取软件使用版权,请联系管理员!").showAndWait();
            }
            if (newValue.getId() != null && isLogin) {
                ClientSession.addAttribute("user", newValue);
                App.toMainStageView();
                if(StringUtils.isNotBlank(validTime)){
                    new MyAlert(AlertType.WARNING, validTime).showAndWait();
                }
            } else {
                if(null != newValue && newValue.getRoot() == 2){
                    // 登陆节点不可用
                    new MyAlert(AlertType.WARNING, "非法用户或未授权用户,请联系管理员!").showAndWait();
                }else if(null != newValue && newValue.getRoot() == 3){
                    btn_Login.setText("登  录");
                    btn_Login.setDisable(false);
                    new MyAlert(AlertType.WARNING, "用户名或密码错误!").showAndWait();
                }else if(null != newValue && newValue.getRoot() == 4){
                    // 登陆节点不可用
                    new MyAlert(AlertType.WARNING, "科目余额表模版未指定,请联系管理员!").showAndWait();
                }
            }
        });
    }

    @FXML
    public void forget(ActionEvent actionEvent) {
        AbstractApp.showView(ForgetPasswordView.class);
    }

    /**
     * 密码校验线程
     */
    private static class VerifyTask extends Task<LoginDto> {

        @Value("${url.checkNode}")
        private String checkUrl;
        LoginService service = (LoginService) SpringUtil.getBean("LoginServiceImpl");
        SoftwareMapModelService softwareMapModelService = (SoftwareMapModelService) SpringUtil.getBean("SoftwareMapModelServiceImpl");
        SubMatchingService subMatchingService = (SubMatchingService)SpringUtil.getBean("SubMatchingServiceImpl");
        private String username;
        private String password;
        private String saltPassword;


        VerifyTask(String username, String password) {
            this.username = username;
            this.password = password;
            this.saltPassword = new SaltUtil(username, "MD5").encode(password);
        }

        @Override
        protected LoginDto call()  {

            HashMap<String, Object> request = new HashMap<String ,Object >();
            request.put("email", DesUtils.encrypt(username, "Client_taxSw@9801",false));
            try {
                String rtnVal =  DesUtils.decrypt(service.getCertfyInfo(request),"Server_taxSw@9802",false);
                if (StringUtils.isBlank(rtnVal)) {
                    LoginDto rtnDto = new LoginDto();
                    rtnDto.setRoot(2);
                    return rtnDto;
                }
                JSONObject json = new JSONObject(rtnVal);

                LoginDto loginDto = service.verify(username, saltPassword);
                LoginDto userInfo = service.getUserInfo(username);

                if (null!= userInfo && null == loginDto) {
                    LoginDto rtnDto = new LoginDto();
                    rtnDto.setRoot(3);
                    return rtnDto;
                } else if (null != loginDto ) {
                    this.syncMapping(json,loginDto);
                    return loginDto;
                }else {
                    //int num =  softwareMapModelService.getBaseMapper().selectCount(new QueryWrapper<>());
                    if(json.get("softWareMapModel") instanceof JSONNull ) {
                        LoginDto rtnDto = new LoginDto();
                        rtnDto.setRoot(4);
                        return rtnDto;
                    }else{
                        if(!"a123456".equals(this.password)){
                            LoginDto rtnDto = new LoginDto();
                            rtnDto.setRoot(3);
                            return rtnDto;
                        }
                        softwareMapModelService.getBaseMapper().delete(new QueryWrapper<>());
                        JSONObject jsonObject = (JSONObject)json.get("softWareMapModel");
                        if(null == jsonObject){
                            LoginDto rtnDto = new LoginDto();
                            rtnDto.setRoot(4);
                            return rtnDto;
                        }
                        SoftwareMapModel softWareMapModel = new SoftwareMapModel();
                        softWareMapModel.setId(Long.valueOf(transformation(jsonObject.get("id"))));
                        softWareMapModel.setSoftwareName(transformation(jsonObject.get("softwareName")));
                        softWareMapModel.setSourceSubNo(transformation(jsonObject.get("sourceSubNo")));
                        softWareMapModel.setDestSubNo(transformation(jsonObject.get("destSubNo")));
                        softWareMapModel.setSourceSubName(transformation(jsonObject.get("sourceSubName")));
                        softWareMapModel.setDestSubName(transformation(jsonObject.get("destSubName")));
                        softWareMapModel.setSourceOpenType(transformation(jsonObject.get("sourceOpenType")));
                        softWareMapModel.setDestOpenType(transformation(jsonObject.get("destOpenType")));
                        softWareMapModel.setSourceOpenBal(transformation(jsonObject.get("sourceOpenBal")));
                        softWareMapModel.setDestOpenBal(transformation(jsonObject.get("destOpenBal")));
                        softWareMapModel.setDestOpenBalQ(transformation(jsonObject.get("destOpenBalQ")));
                        softWareMapModel.setDestOpenBalM(transformation(jsonObject.get("destOpenBalM")));
                        softWareMapModel.setSourceCurrentDebit(transformation(jsonObject.get("sourceCurrentDebit")));
                        softWareMapModel.setDestCurrentDebit(transformation(jsonObject.get("destCurrentDebit")));
                        softWareMapModel.setDestCurrentDebitQ(transformation(jsonObject.get("destCurrentDebitQ")));
                        softWareMapModel.setDestCurrentDebitM(transformation(jsonObject.get("destCurrentDebitM")));
                        softWareMapModel.setSourceCurrentCredit(transformation(jsonObject.get("sourceCurrentCredit")));
                        softWareMapModel.setDestCurrentCredit(transformation(jsonObject.get("destCurrentCredit")));
                        softWareMapModel.setDestCurrentCreditQ(transformation(jsonObject.get("destCurrentCreditQ")));
                        softWareMapModel.setDestCurrentCreditM(transformation(jsonObject.get("destCurrentCreditM")));
                        softWareMapModel.setSourceEndType(transformation(jsonObject.get("sourceEndType")));
                        softWareMapModel.setDestEndType(transformation(jsonObject.get("destEndType")));
                        softWareMapModel.setSourceEndBal(transformation(jsonObject.get("sourceEndBal")));
                        softWareMapModel.setDestEndBal(transformation(jsonObject.get("destEndBal")));
                        softWareMapModel.setDestEndBalQ(transformation(jsonObject.get("destEndBalQ")));
                        softWareMapModel.setDestEndBalM(transformation(jsonObject.get("destEndBalM")));
                        softwareMapModelService.getBaseMapper().insert(softWareMapModel);
                        LoginInfo loginBean = new LoginInfo();
                        loginBean.setId(transformation(json.get("contactEmail")));
                        loginBean.setContacts(transformation(json.get("contactPerson")));
                        loginBean.setCreditCode(transformation(json.get("taxpayerNo")));
                        loginBean.setCompanyName(transformation(json.get("companyName")));
                        loginBean.setEmail(transformation(json.get("contactEmail")));
                        loginBean.setTel(transformation(json.get("contactMobile")));
                        loginBean.setName(transformation(json.get("contactPerson")));
                        loginBean.setTaxpayerNature(transformation(json.get("taxpayerNature")));
                        loginBean.setIndexStandardType(transformation(json.get("indexStandardType")));
                        loginBean.setType(transformation(json.get("type")));
                        loginBean.setPassword(new SaltUtil(loginBean.getId(), "MD5").encode("a123456"));
                        loginBean.setRoot(1);
                        loginBean.setSoftName(softWareMapModel.getSoftwareName());
                        loginBean.setSoftId(String.valueOf(softWareMapModel.getId()));
                        service.getBaseMapper().delete(new QueryWrapper<>());
                        service.save(loginBean);
                        loginDto = new LoginDto();
                        BeanUtils.copyProperties(loginBean,loginDto);

                    };
                    this.syncMapping(json,loginDto);
                    return loginDto;
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            return new LoginDto();
        }

        private boolean syncMapping(JSONObject json,LoginDto loginDto){
            if(!"1".equals(loginDto.getType())){
                if(json.get("systemSubMatchingBOList") instanceof JSONNull ) {
                    ;
                }else{
                    JSONArray jsonArray = json.getJSONArray("systemSubMatchingBOList");
                    List<SystemSubMatchingBO> systemSubMatchingBOS = jsonArray.toList(SystemSubMatchingBO.class);
                    List<SubMatching> subMatchings = new ArrayList<>();
                    systemSubMatchingBOS.forEach(systemSubMatchingBO -> {
                        SubMatching subMatching = new SubMatching();
                        BeanUtils.copyProperties(systemSubMatchingBO,subMatching);
                        if(null != subMatching){
                            subMatchingService.insertMatch(subMatching);
                        }
                    });
                }
            }
            return true;
        }

        private String transformation(Object obj){
            if(null==obj){
                return "";
            }else{
                return String.valueOf(obj);
            }
        }

    }
}
